/*
 * Copyright © 2024-2025 Wenze Wei
 *
 * This file is part of StadionOS.
 *
 * This Source Code Form is subject to the terms of the GNU General Public License, v. 2.0.
 * You can obtain a copy of the GPL at
 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 */

#include "../include/time.h"

/**
 * @brief Define a list of timezones with their UTC offsets and DST information.
 *
 * This structure array contains various timezones with their respective UTC offsets and daylight saving time (DST) rules.
 */
struct Tz timezones[MAX_TIMEZONES] = {
    {"Pacific/Midway", -11 * 3600, 0, 0, 0},
    {"Pacific/Niue", -11 * 3600, 0, 0, 0},
    {"Pacific/Pago_Pago", -11 * 3600, 0, 0, 0},
    {"America/Adak", -10 * 3600, 3600, 3, 11},
    {"Pacific/Honolulu", -10 * 3600, 0, 0, 0},
    {"Pacific/Marquesas", -9 * 3600 - 30 * 60, 0, 0, 0},
    {"America/Anchorage", -9 * 3600, 3600, 3, 11},
    {"America/Juneau", -9 * 3600, 3600, 3, 11},
    {"America/Metlakatla", -9 * 3600, 0, 0, 0},
    {"America/Nome", -9 * 3600, 0, 0, 0},
    {"America/Sitka", -9 * 3600, 3600, 3, 11},
    {"America/Yakutat", -9 * 3600, 0, 0, 0},
    {"Pacific/Gambier", -9 * 3600, 0, 0, 0},
    {"America/Los_Angeles", -8 * 3600, 3600, 3, 11},
    {"America/Tijuana", -8 * 3600, 3600, 3, 11},
    {"America/Vancouver", -8 * 3600, 3600, 3, 11},
    {"Pacific/Pitcairn", -8 * 3600, 0, 0, 0},
    {"America/Boise", -7 * 3600, 3600, 3, 11},
    {"America/Cambridge_Bay", -7 * 3600, 3600, 3, 11},
    {"America/Ciudad_Juarez", -7 * 3600, 3600, 3, 11},
    {"America/Creston", -7 * 3600, 0, 0, 0},
    {"America/Dawson", -7 * 3600, 0, 0, 0},
    {"America/Dawson_Creek", -7 * 3600, 0, 0, 0},
    {"America/Denver", -7 * 3600, 3600, 3, 11},
    {"America/Edmonton", -7 * 3600, 3600, 3, 11},
    {"America/Fort_Nelson", -7 * 3600, 0, 0, 0},
    {"America/Hermosillo", -7 * 3600, 0, 0, 0},
    {"America/Inuvik", -7 * 3600, 3600, 3, 11},
    {"America/Mazatlan", -7 * 3600, 0, 0, 0},
    {"America/Phoenix", -7 * 3600, 0, 0, 0},
    {"America/Whitehorse", -7 * 3600, 0, 0, 0},
    {"America/Yellowknife", -7 * 3600, 3600, 3, 11},
    {"America/Bahia_Banderas", -6 * 3600, 0, 0, 0},
    {"America/Belize", -6 * 3600, 0, 0, 0},
    {"America/Chicago", -6 * 3600, 3600, 3, 11},
    {"America/Chihuahua", -6 * 3600, 0, 0, 0},
    {"America/Costa_Rica", -6 * 3600, 0, 0, 0},
    {"America/El_Salvador", -6 * 3600, 0, 0, 0},
    {"America/Guatemala", -6 * 3600, 0, 0, 0},
    {"America/Indiana/Knox", -6 * 3600, 3600, 3, 11},
    {"America/Indiana/Tell_City", -6 * 3600, 3600, 3, 11},
    {"America/Managua", -6 * 3600, 0, 0, 0},
    {"America/Matamoros", -6 * 3600, 0, 0, 0},
    {"America/Menominee", -6 * 3600, 3600, 3, 11},
    {"America/Merida", -6 * 3600, 0, 0, 0},
    {"America/Mexico_City", -6 * 3600, 3600, 3, 11},
    {"America/Monterrey", -6 * 3600, 3600, 3, 11},
    {"America/North_Dakota/Beulah", -6 * 3600, 3600, 3, 11},
    {"America/North_Dakota/Center", -6 * 3600, 3600, 3, 11},
    {"America/North_Dakota/New_Salem", -6 * 3600, 3600, 3, 11},
    {"America/Ojinaga", -6 * 3600, 0, 0, 0},
    {"America/Rankin_Inlet", -6 * 3600, 0, 0, 0},
    {"America/Regina", -6 * 3600, 3600, 3, 11},
    {"America/Resolute", -6 * 3600, 0, 0, 0},
    {"America/Swift_Current", -6 * 3600, 3600, 3, 11},
    {"America/Tegucigalpa", -6 * 3600, 0, 0, 0},
    {"America/Winnipeg", -6 * 3600, 3600, 3, 11},
    {"Pacific/Easter", -6 * 3600, 0, 0, 0},
    {"Pacific/Galapagos", -6 * 3600, 0, 0, 0},
    {"America/Atikokan", -5 * 3600, 0, 0, 0},
    {"America/Bogota", -5 * 3600, 0, 0, 0},
    {"America/Cancun", -5 * 3600, 0, 0, 0},
    {"America/Cayman", -5 * 3600, 0, 0, 0},
    {"America/Detroit", -5 * 3600, 3600, 3, 11},
    {"America/Eirunepe", -5 * 3600, 0, 0, 0},
    {"America/Grand_Turk", -5 * 3600, 3600, 3, 11},
    {"America/Guayaquil", -5 * 3600, 0, 0, 0},
    {"America/Havana", -5 * 3600, 3600, 3, 11},
    {"America/Indiana/Indianapolis", -5 * 3600, 3600, 3, 11},
    {"America/Indiana/Marengo", -5 * 3600, 0, 0, 0},
    {"America/Indiana/Petersburg", -5 * 3600, 0, 0, 0},
    {"America/Indiana/Vevay", -5 * 3600, 0, 0, 0},
    {"America/Indiana/Vincennes", -5 * 3600, 3600, 3, 11},
    {"America/Indiana/Winamac", -5 * 3600, 0, 0, 0},
    {"America/Iqaluit", -5 * 3600, 0, 0, 0},
    {"America/Jamaica", -5 * 3600, 0, 0, 0},
    {"America/Kentucky/Louisville", -5 * 3600, 3600, 3, 11},
    {"America/Kentucky/Monticello", -5 * 3600, 3600, 3, 11},
    {"America/Lima", -5 * 3600, 0, 0, 0},
    {"America/Nassau", -5 * 3600, 3600, 3, 11},
    {"America/New_York", -5 * 3600, 3600, 3, 11},
    {"America/Panama", -5 * 3600, 0, 0, 0},
    {"America/Port-au-Prince", -5 * 3600, 3600, 3, 11},
    {"America/Rio_Branco", -5 * 3600, 0, 0, 0},
    {"America/Toronto", -5 * 3600, 3600, 3, 11},
    {"America/Anguilla", -4 * 3600, 0, 0, 0},
    {"America/Antigua", -4 * 3600, 0, 0, 0},
    {"America/Aruba", -4 * 3600, 0, 0, 0},
    {"America/Asuncion", -4 * 3600, 3600, 10, 3},
    {"America/Barbados", -4 * 3600, 0, 0, 0},
    {"America/Blanc-Sablon", -4 * 3600, 0, 0, 0},
    {"America/Boa_Vista", -4 * 3600, 0, 0, 0},
    {"America/Campo_Grande", -4 * 3600, 0, 0, 0},
    {"America/Caracas", -4 * 3600, 0, 0, 0},
    {"America/Cuiaba", -4 * 3600, 3600, 10, 3},
    {"America/Curacao", -4 * 3600, 0, 0, 0},
    {"America/Dominica", -4 * 3600, 0, 0, 0},
    {"America/Glace_Bay", -4 * 3600, 3600, 3, 11},
    {"America/Goose_Bay", -4 * 3600, 0, 0, 0},
    {"America/Grenada", -4 * 3600, 0, 0, 0},
    {"America/Guadeloupe", -4 * 3600, 0, 0, 0},
    {"America/Guyana", -4 * 3600, 0, 0, 0},
    {"America/Halifax", -4 * 3600, 3600, 3, 11},
    {"America/Kralendijk", -4 * 3600, 0, 0, 0},
    {"America/La_Paz", -4 * 3600, 0, 0, 0},
    {"America/Lower_Princes", -4 * 3600, 0, 0, 0},
    {"America/Manaus", -4 * 3600, 0, 0, 0},
    {"America/Marigot", -4 * 3600, 0, 0, 0},
    {"America/Martinique", -4 * 3600, 0, 0, 0},
    {"America/Moncton", -4 * 3600, 3600, 3, 11},
    {"America/Montserrat", -4 * 3600, 0, 0, 0},
    {"America/Porto_Velho", -4 * 3600, 0, 0, 0},
    {"America/Port_of_Spain", -4 * 3600, 0, 0, 0},
    {"America/Puerto_Rico", -4 * 3600, 0, 0, 0},
    {"America/Santiago", -4 * 3600, 3600, 10, 3},
    {"America/Santo_Domingo", -4 * 3600, 0, 0, 0},
    {"America/St_Barthelemy", -4 * 3600, 0, 0, 0},
    {"America/St_Kitts", -4 * 3600, 0, 0, 0},
    {"America/St_Lucia", -4 * 3600, 0, 0, 0},
    {"America/St_Thomas", -4 * 3600, 0, 0, 0},
    {"America/St_Vincent", -4 * 3600, 0, 0, 0},
    {"America/Thule", -4 * 3600, 3600, 3, 11},
    {"America/Tortola", -4 * 3600, 0, 0, 0},
    {"Atlantic/Bermuda", -4 * 3600, 3600, 3, 11},
    {"America/St_Johns", -3.5 * 3600, 0, 0, 0},
    {"America/Araguaina", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Buenos_Aires", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Catamarca", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Cordoba", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Jujuy", -3 * 3600, 0, 0, 0},
    {"America/Argentina/La_Rioja", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Mendoza", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Rio_Gallegos", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Salta", -3 * 3600, 0, 0, 0},
    {"America/Argentina/San_Juan", -3 * 3600, 0, 0, 0},
    {"America/Argentina/San_Luis", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Tucuman", -3 * 3600, 0, 0, 0},
    {"America/Argentina/Ushuaia", -3 * 3600, 0, 0, 0},
    {"America/Bahia", -3 * 3600, 0, 0, 0},
    {"America/Belem", -3 * 3600, 0, 0, 0},
    {"America/Cayenne", -3 * 3600, 0, 0, 0},
    {"America/Fortaleza", -3 * 3600, 0, 0, 0},
    {"America/Maceio", -3 * 3600, 0, 0, 0},
    {"America/Miquelon", -3 * 3600, 0, 0, 0},
    {"America/Montevideo", -3 * 3600, 0, 0, 0},
    {"America/Paramaribo", -3 * 3600, 0, 0, 0},
    {"America/Punta_Arenas", -3 * 3600, 0, 0, 0},
    {"America/Recife", -3 * 3600, 0, 0, 0},
    {"America/Santarem", -3 * 3600, 0, 0, 0},
    {"America/Sao_Paulo", -3 * 3600, 0, 0, 0},
    {"Antarctica/Palmer", -3 * 3600, 0, 0, 0},
    {"Antarctica/Rothera", -3 * 3600, 0, 0, 0},
    {"Atlantic/Stanley", -3 * 3600, 0, 0, 0},
    {"America/Noronha", -2 * 3600, 0, 0, 0},
    {"America/Nuuk", -2 * 3600, 3600, 3, 11},
    {"Atlantic/South_Georgia", -2 * 3600, 0, 0, 0},
    {"America/Scoresbysund", -1 * 3600, 3600, 3, 10},
    {"Atlantic/Azores", -1 * 3600, 3600, 3, 10},
    {"Atlantic/Cape_Verde", -1 * 3600, 0, 0, 0},
    {"Africa/Abidjan", 0, 0, 0, 0},
    {"Africa/Accra", 0, 0, 0, 0},
    {"Africa/Bamako", 0, 0, 0, 0},
    {"Africa/Banjul", 0, 0, 0, 0},
    {"Africa/Bissau", 0, 0, 0, 0},
    {"Africa/Casablanca", 0, 0, 0, 0},
    {"Africa/Conakry", 0, 0, 0, 0},
    {"Africa/Dakar", 0, 0, 0, 0},
    {"Africa/El_Aaiun", 0, 0, 0, 0},
    {"Africa/Freetown", 0, 0, 0, 0},
    {"Africa/Lome", 0, 0, 0, 0},
    {"Africa/Monrovia", 0, 0, 0, 0},
    {"Africa/Nouakchott", 0, 0, 0, 0},
    {"Africa/Ouagadougou", 0, 0, 0, 0},
    {"Africa/Sao_Tome", 0, 0, 0, 0},
    {"America/Danmarkshavn", 0, 0, 0, 0},
    {"Antarctica/Troll", 0, 0, 0, 0},
    {"Atlantic/Canary", 0, 0, 0, 0},
    {"Atlantic/Faroe", 0, 0, 0, 0},
    {"Atlantic/Madeira", 0, 0, 0, 0},
    {"Atlantic/Reykjavik", 0, 0, 0, 0},
    {"Atlantic/St_Helena", 0, 0, 0, 0},
    {"Europe/Dublin", 0, 3600, 3, 10},
    {"Europe/Guernsey", 0, 0, 0, 0},
    {"Europe/Isle_of_Man", 0, 0, 0, 0},
    {"Europe/Jersey", 0, 0, 0, 0},
    {"Europe/Lisbon", 0, 0, 0, 0},
    {"Europe/London", 0, 3600, 3, 10},
    {"Africa/Algiers", 1 * 3600, 0, 0, 0},
    {"Africa/Bangui", 1 * 3600, 0, 0, 0},
    {"Africa/Brazzaville", 1 * 3600, 0, 0, 0},
    {"Africa/Ceuta", 1 * 3600, 3600, 3, 10},
    {"Africa/Douala", 1 * 3600, 0, 0, 0},
    {"Africa/Kinshasa", 1 * 3600, 0, 0, 0},
    {"Africa/Lagos", 1 * 3600, 0, 0, 0},
    {"Africa/Libreville", 1 * 3600, 0, 0, 0},
    {"Africa/Luanda", 1 * 3600, 0, 0, 0},
    {"Africa/Malabo", 1 * 3600, 0, 0, 0},
    {"Africa/Ndjamena", 1 * 3600, 0, 0, 0},
    {"Africa/Niamey", 1 * 3600, 0, 0, 0},
    {"Africa/Porto-Novo", 1 * 3600, 0, 0, 0},
    {"Africa/Tunis", 1 * 3600, 0, 0, 0},
    {"Africa/Windhoek", 1 * 3600, 3600, 9, 10},
    {"Arctic/Longyearbyen", 1 * 3600, 3600, 3, 10},
    {"Europe/Amsterdam", 1 * 3600, 3600, 3, 10},
    {"Europe/Andorra", 1 * 3600, 3600, 3, 10},
    {"Europe/Belgrade", 1 * 3600, 3600, 3, 10},
    {"Europe/Berlin", 1 * 3600, 3600, 3, 10},
    {"Europe/Bratislava", 1 * 3600, 3600, 3, 10},
    {"Europe/Brussels", 1 * 3600, 3600, 3, 10},
    {"Europe/Budapest", 1 * 3600, 3600, 3, 10},
    {"Europe/Copenhagen", 1 * 3600, 3600, 3, 10},
    {"Europe/Gibraltar", 1 * 3600, 3600, 3, 10},
    {"Europe/Ljubljana", 1 * 3600, 3600, 3, 10},
    {"Europe/Luxembourg", 1 * 3600, 3600, 3, 10},
    {"Europe/Madrid", 1 * 3600, 3600, 3, 10},
    {"Europe/Malta", 1 * 3600, 3600, 3, 10},
    {"Europe/Monaco", 1 * 3600, 3600, 3, 10},
    {"Europe/Oslo", 1 * 3600, 3600, 3, 10},
    {"Europe/Paris", 1 * 3600, 3600, 3, 10},
    {"Europe/Podgorica", 1 * 3600, 3600, 3, 10},
    {"Europe/Prague", 1 * 3600, 3600, 3, 10},
    {"Europe/Rome", 1 * 3600, 3600, 3, 10},
    {"Europe/San_Marino", 1 * 3600, 3600, 3, 10},
    {"Europe/Sarajevo", 1 * 3600, 3600, 3, 10},
    {"Europe/Skopje", 1 * 3600, 3600, 3, 10},
    {"Europe/Stockholm", 1 * 3600, 3600, 3, 10},
    {"Europe/Tirane", 1 * 3600, 3600, 3, 10},
    {"Europe/Vaduz", 1 * 3600, 3600, 3, 10},
    {"Europe/Vatican", 1 * 3600, 3600, 3, 10},
    {"Europe/Vienna", 1 * 3600, 3600, 3, 10},
    {"Europe/Warsaw", 1 * 3600, 3600, 3, 10},
    {"Europe/Zagreb", 1 * 3600, 3600, 3, 10},
    {"Europe/Zurich", 1 * 3600, 3600, 3, 10},
    {"Africa/Blantyre", 2 * 3600, 3600, 3, 10},
    {"Africa/Bujumbura", 2 * 3600, 3600, 3, 10},
    {"Africa/Cairo", 2 * 3600, 3600, 4, 10},
    {"Africa/Gaborone", 2 * 3600, 3600, 3, 10},
    {"Africa/Harare", 2 * 3600, 3600, 3, 10},
    {"Africa/Johannesburg", 2 * 3600, 0, 0, 0},
    {"Africa/Juba", 2 * 3600, 3600, 3, 10},
    {"Africa/Khartoum", 2 * 3600, 3600, 3, 10},
    {"Africa/Kigali", 2 * 3600, 3600, 3, 10},
    {"Africa/Lubumbashi", 2 * 3600, 3600, 3, 10},
    {"Africa/Lusaka", 2 * 3600, 3600, 3, 10},
    {"Africa/Maputo", 2 * 3600, 3600, 3, 10},
    {"Africa/Maseru", 2 * 3600, 3600, 3, 10},
    {"Africa/Mbabane", 2 * 3600, 3600, 3, 10},
    {"Africa/Tripoli", 2 * 3600, 3600, 3, 10},
    {"Asia/Beirut", 2 * 3600, 3600, 3, 10},
    {"Asia/Famagusta", 2 * 3600, 3600, 3, 10},
    {"Asia/Gaza", 2 * 3600, 3600, 3, 10},
    {"Asia/Hebron", 2 * 3600, 3600, 3, 10},
    {"Asia/Jerusalem", 2 * 3600, 3600, 3, 10},
    {"Asia/Nicosia", 2 * 3600, 3600, 3, 10},
    {"Europe/Athens", 2 * 3600, 3600, 3, 10},
    {"Europe/Bucharest", 2 * 3600, 3600, 3, 10},
    {"Europe/Chisinau", 2 * 3600, 3600, 3, 10},
    {"Europe/Helsinki", 2 * 3600, 3600, 3, 10},
    {"Europe/Kaliningrad", 2 * 3600, 0, 0, 0},
    {"Europe/Kyiv", 2 * 3600, 3600, 3, 10},
    {"Europe/Mariehamn", 2 * 3600, 3600, 3, 10},
    {"Europe/Riga", 2 * 3600, 3600, 3, 10},
    {"Europe/Sofia", 2 * 3600, 3600, 3, 10},
    {"Europe/Tallinn", 2 * 3600, 3600, 3, 10},
    {"Europe/Vilnius", 2 * 3600, 3600, 3, 10},
    {"Africa/Addis_Ababa", 3 * 3600, 0, 0, 0},
    {"Africa/Asmara", 3 * 3600, 0, 0, 0},
    {"Africa/Dar_es_Salaam", 3 * 3600, 0, 0, 0},
    {"Africa/Djibouti", 3 * 3600, 0, 0, 0},
    {"Africa/Kampala", 3 * 3600, 0, 0, 0},
    {"Africa/Mogadishu", 3 * 3600, 0, 0, 0},
    {"Africa/Nairobi", 3 * 3600, 0, 0, 0},
    {"Antarctica/Syowa", 3 * 3600, 0, 0, 0},
    {"Asia/Aden", 3 * 3600, 0, 0, 0},
    {"Asia/Amman", 3 * 3600, 3600, 3, 10},
    {"Asia/Baghdad", 3 * 3600, 3600, 3, 10},
    {"Asia/Bahrain", 3 * 3600, 0, 0, 0},
    {"Asia/Damascus", 3 * 3600, 3600, 3, 10},
    {"Asia/Kuwait", 3 * 3600, 0, 0, 0},
    {"Asia/Qatar", 3 * 3600, 0, 0, 0},
    {"Asia/Riyadh", 3 * 3600, 0, 0, 0},
    {"Europe/Istanbul", 3 * 3600, 3600, 3, 10},
    {"Europe/Kirov", 3 * 3600, 0, 0, 0},
    {"Europe/Minsk", 3 * 3600, 3600, 3, 10},
    {"Europe/Moscow", 3 * 3600, 3600, 3, 10},
    {"Europe/Simferopol", 3 * 3600, 3600, 3, 10},
    {"Europe/Volgograd", 3 * 3600, 3600, 3, 10},
    {"Indian/Antananarivo", 3 * 3600, 0, 0, 0},
    {"Indian/Comoro", 3 * 3600, 0, 0, 0},
    {"Indian/Mayotte", 3 * 3600, 0, 0, 0},
    {"Asia/Tehran", 3.5 * 3600, 3600, 3, 9},
    {"Asia/Baku", 4 * 3600, 3600, 3, 10},
    {"Asia/Dubai", 4 * 3600, 0, 0, 0},
    {"Asia/Muscat", 4 * 3600, 0, 0, 0},
    {"Asia/Tbilisi", 4 * 3600, 3600, 3, 10},
    {"Asia/Yerevan", 4 * 3600, 0, 0, 0},
    {"Europe/Astrakhan", 4 * 3600, 0, 0, 0},
    {"Europe/Samara", 4 * 3600, 0, 0, 0},
    {"Europe/Saratov", 4 * 3600, 0, 0, 0},
    {"Europe/Ulyanovsk", 4 * 3600, 0, 0, 0},
    {"Indian/Mahe", 4 * 3600, 0, 0, 0},
    {"Indian/Mauritius", 4 * 3600, 0, 0, 0},
    {"Indian/Reunion", 4 * 3600, 0, 0, 0},
    {"Asia/Kabul", 4.5 * 3600, 0, 0, 0},
    {"Antarctica/Mawson", 5 * 3600, 0, 0, 0},
    {"Asia/Aqtau", 5 * 3600, 0, 0, 0},
    {"Asia/Aqtobe", 5 * 3600, 0, 0, 0},
    {"Asia/Ashgabat", 5 * 3600, 0, 0, 0},
    {"Asia/Bishkek", 5 * 3600, 0, 0, 0},
    {"Asia/Dushanbe", 5 * 3600, 0, 0, 0},
    {"Asia/Karachi", 5 * 3600, 0, 0, 0},
    {"Asia/Oral", 5 * 3600, 0, 0, 0},
    {"Asia/Samarkand", 5 * 3600, 0, 0, 0},
    {"Asia/Tashkent", 5 * 3600, 0, 0, 0},
    {"Indian/Chagos", 5 * 3600, 0, 0, 0},
    {"Indian/Kerguelen", 5 * 3600, 0, 0, 0},
    {"Indian/Maldives", 5 * 3600, 0, 0, 0},
    {"Asia/Colombo", 5.5 * 3600, 0, 0, 0},
    {"Asia/Kolkata", 5.5 * 3600, 0, 0, 0},
    {"Asia/Kathmandu", 5.75 * 3600, 0, 0, 0},
    {"Asia/Almaty", 6 * 3600, 0, 0, 0},
    {"Asia/Bishkek", 6 * 3600, 0, 0, 0},
    {"Asia/Dhaka", 6 * 3600, 0, 0, 0},
    {"Asia/Qyzylorda", 6 * 3600, 0, 0, 0},
    {"Asia/Thimphu", 6 * 3600, 0, 0, 0},
    {"Asia/Urumqi", 6 * 3600, 0, 0, 0},
    {"Indian/Chagos", 6 * 3600, 0, 0, 0},
    {"Asia/Rangoon", 6.5 * 3600, 0, 0, 0},
    {"Indian/Cocos", 6.5 * 3600, 0, 0, 0},
    {"Asia/Bangkok", 7 * 3600, 0, 0, 0},
    {"Asia/Ho_Chi_Minh", 7 * 3600, 0, 0, 0},
    {"Asia/Hovd", 7 * 3600, 0, 0, 0},
    {"Asia/Jakarta", 7 * 3600, 0, 0, 0},
    {"Asia/Phnom_Penh", 7 * 3600, 0, 0, 0},
    {"Asia/Pontianak", 7 * 3600, 0, 0, 0},
    {"Asia/Vientiane", 7 * 3600, 0, 0, 0},
    {"Indian/Christmas", 7 * 3600, 0, 0, 0},
    {"Asia/Brunei", 8 * 3600, 0, 0, 0},
    {"Asia/Chongqing", 8 * 3600, 0, 0, 0},
    {"Asia/Hong_Kong", 8 * 3600, 0, 0, 0},
    {"Asia/Kuala_Lumpur", 8 * 3600, 0, 0, 0},
    {"Asia/Kuching", 8 * 3600, 0, 0, 0},
    {"Asia/Macau", 8 * 3600, 0, 0, 0},
    {"Asia/Makassar", 8 * 3600, 0, 0, 0},
    {"Asia/Manila", 8 * 3600, 0, 0, 0},
    {"Asia/Shanghai", 8 * 3600, 0, 0, 0},
    {"Asia/Singapore", 8 * 3600, 0, 0, 0},
    {"Asia/Taipei", 8 * 3600, 0, 0, 0},
    {"Indian/Cocos", 8 * 3600, 0, 0, 0},
    {"Australia/Eucla", 8.75 * 3600, 0, 0, 0},
    {"Asia/Dili", 9 * 3600, 0, 0, 0},
    {"Asia/Jayapura", 9 * 3600, 0, 0, 0},
    {"Asia/Pyongyang", 9 * 3600, 0, 0, 0},
    {"Asia/Seoul", 9 * 3600, 0, 0, 0},
    {"Asia/Tokyo", 9 * 3600, 0, 0, 0},
    {"Pacific/Palau", 9 * 3600, 0, 0, 0},
    {"Australia/Adelaide", 9.5 * 3600, 3600, 10, 4},
    {"Australia/Broken_Hill", 9.5 * 3600, 3600, 10, 4},
    {"Australia/Darwin", 9.5 * 3600, 0, 0, 0},
    {"Australia/North", 9.5 * 3600, 0, 0, 0},
    {"Australia/South", 9.5 * 3600, 3600, 10, 4},
    {"Australia/Yancowinna", 9.5 * 3600, 0, 0, 0},
    {"Australia/Brisbane", 10 * 3600, 0, 0, 0},
    {"Australia/Canberra", 10 * 3600, 3600, 10, 4},
    {"Australia/Currie", 10 * 3600, 3600, 10, 4},
    {"Australia/Hobart", 10 * 3600, 3600, 10, 4},
    {"Australia/Lindeman", 10 * 3600, 0, 0, 0},
    {"Australia/Melbourne", 10 * 3600, 3600, 10, 4},
    {"Australia/Sydney", 10 * 3600, 3600, 10, 4},
    {"Pacific/Guam", 10 * 3600, 0, 0, 0},
    {"Pacific/Port_Moresby", 10 * 3600, 0, 0, 0},
    {"Pacific/Saipan", 10 * 3600, 0, 0, 0},
    {"Asia/Yakutsk", 10 * 3600, 0, 0, 0},
    {"Australia/Lord_Howe", 10.5 * 3600, 3600, 10, 4},
    {"Asia/Irkutsk", 11 * 3600, 0, 0, 0},
    {"Asia/Khandyga", 11 * 3600, 0, 0, 0},
    {"Asia/Ust-Nera", 11 * 3600, 0, 0, 0},
    {"Asia/Vladivostok", 11 * 3600, 0, 0, 0},
    {"Pacific/Efate", 11 * 3600, 0, 0, 0},
    {"Pacific/Guadalcanal", 11 * 3600, 0, 0, 0},
    {"Pacific/Kosrae", 11 * 3600, 0, 0, 0},
    {"Pacific/Norfolk", 11 * 3600, 0, 0, 0},
    {"Pacific/Noumea", 11 * 3600, 0, 0, 0},
    {"Pacific/Pohnpei", 11 * 3600, 0, 0, 0},
    {"Pacific/Enderbury", 11.5 * 3600, 0, 0, 0},
    {"Pacific/Funafuti", 12 * 3600, 0, 0, 0},
    {"Asia/Anadyr", 12 * 3600, 0, 0, 0},
    {"Asia/Kamchatka", 12 * 3600, 0, 0, 0},
    {"Pacific/Auckland", 12 * 3600, 3600, 9, 4},
    {"Pacific/Fiji", 12 * 3600, 0, 0, 0},
    {"Pacific/Kwajalein", 12 * 3600, 0, 0, 0},
    {"Pacific/Majuro", 12 * 3600, 0, 0, 0},
    {"Pacific/Nauru", 12 * 3600, 0, 0, 0},
    {"Pacific/Tarawa", 12 * 3600, 0, 0, 0},
    {"Pacific/Wake", 12 * 3600, 0, 0, 0},
    {"Pacific/Wallis", 12 * 3600, 0, 0, 0},
    {"Pacific/Chatham", 12.75 * 3600, 3600, 9, 4},
    {"Pacific/Apia", 13 * 3600, 0, 0, 0},
    {"Pacific/Enderbury", 13 * 3600, 0, 0, 0},
    {"Pacific/Fakaofo", 13 * 3600, 0, 0, 0},
    {"Pacific/Tongatapu", 13 * 3600, 0, 0, 0},
    {"Pacific/Kiritimati", 14 * 3600, 0, 0, 0}
};

/**
 * @brief Determine if the given time is within the daylight saving time (DST) period.
 *
 * @param tz Pointer to a Tz structure containing the timezone information.
 * @param tm Pointer to a Ttm structure containing the time to check.
 * @return 1 if the time is within the DST period, 0 otherwise.
 */
int Sis_dst(struct Tz *tz, struct Ttm *tm) {
    if (tm->tm_mon >= tz->dst_start_month && tm->tm_mon < tz->dst_end_month) {
        return 1;
    }
    return 0;
}

/**
 * @brief Convert a UTC time to local time based on the given timezone.
 *
 * This function takes a time_t value representing UTC time and a timezone structure,
 * and returns a new Ttm structure representing the equivalent local time.
 * It accounts for the timezone's UTC offset and DST rules.
 *
 * @param timer Pointer to a time_t value representing the UTC time to convert.
 * @param tz Pointer to a Tz structure containing the timezone information.
 * @return A pointer to a new Ttm structure representing the local time.
 */
struct Ttm *Sconvert_to_localtime(const time_t *timer, struct Tz *tz) {
    struct tm *utc_tm = gmtime(timer);
    struct Ttm *local_tm = Smalloc(sizeof(struct Ttm));

    local_tm->tm_year = utc_tm->tm_year;
    local_tm->tm_mon = utc_tm->tm_mon;
    local_tm->tm_mday = utc_tm->tm_mday;
    local_tm->tm_hour = utc_tm->tm_hour + (tz->utc_offset / 3600); // 添加 UTC 偏移
    local_tm->tm_min = utc_tm->tm_min;
    local_tm->tm_sec = utc_tm->tm_sec;
    local_tm->tm_isdst = 0;

    if (Sis_dst(tz, local_tm)) {
        local_tm->tm_hour += (tz->dst_offset / 3600); // 应用夏令时偏移
        local_tm->tm_isdst = 1;
    }

    if (local_tm->tm_hour >= 24) {
        local_tm->tm_hour -= 24;
        local_tm->tm_mday++;
    } else if (local_tm->tm_hour < 0) {
        local_tm->tm_hour += 24;
        local_tm->tm_mday--;
    }

    if (local_tm->tm_mday > 31) {
        local_tm->tm_mday = 1;
        local_tm->tm_mon++;
    } else if (local_tm->tm_mday < 1) {
        local_tm->tm_mday = 31;
        local_tm->tm_mon--;
    }

    return local_tm;
}
